# -*- coding: utf-8 -*-
# @Time    : 2018-02-19 10:34
# @Author  : Wesley
# @File    : lesson8.py
import re


def valid_string(attr_name, empty_allowed=True, regx=None, acceptable=None):
    '''
    校验字符串
    :param attr_name:
    :param empty_allowed:
    :param regx:
    :param acceptable:
    :return:
    '''
    def decorator(cls):
        name = "__" + attr_name #创建一个私有属性

        def getter(self):
            return getattr(self, name)

        def setter(self, value):
            assert isinstance(value, str), (attr_name + " must be a string")
            if not empty_allowed and not value:
                raise ValueError("{0} may not be empty".format(attr_name))

            if ((acceptable is not None and value not in acceptable) or (regx is not None and not regx.match(value))):
                raise ValueError("{attr_name} cannot be set to {value}".format(**locals()))

            setattr(self, name, value)

        setattr(cls, attr_name, GenericDescriptor(getter, setter))
        return cls
    return decorator



def valid_number(attr_name, minimun, maximun):
    '''
    校验数字
    :param attr_name:
    :param minimun:
    :param maximun:
    :return:
    '''
    name = "__"+attr_name
    def decorator(cls):
        def getter(self,name):
            return getattr(self,name)

        def setter(self,value):
            assert isinstance(value,int) or isinstance(value,float),(attr_name +" must be a int or a float")

            if value > maximun:
                raise  ValueError("大于最大值了")
            elif value < minimun:
                raise  ValueError("小于最小值了")
            else:
                setattr(self, name, value)


        setattr(cls, attr_name, GenericDescriptor(getter, setter))
        return cls
    return decorator


class GenericDescriptor:
    def __init__(self,getter,setter):
        self.getter = getter
        self.setter = setter

    def __get__(self,instance,owner=None):
        if instance is None:
            return self
        return self.getter(instance)

    def __set__(self,instance,value):
        return self.setter(instance,value)




'''
定义属性校验
'''
@valid_string("name",empty_allowed=False)
@valid_string("productid",empty_allowed=False,regx=re.compile(r"[A-Z]{3}\d{4}"))
@valid_string("category",empty_allowed=False,acceptable=frozenset(["Consumables","Hardware","Software","Media"]))
@valid_number("price",minimun=0,maximun=1000)
@valid_number("quantity",minimun=1,maximun=1000)
class StockItem(object):
    def __init__(self,name,productid,category,price,quantity):
        self.name = name
        self.productid = productid
        self.category = category
        self.price = price
        self.quantity = quantity

    def showMsg(self):
        print(self.name+"-----"+repr(getattr(self,"__price")))

